
package com.tianya.utils;

import com.tianya.common.config.Config;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

public class FastDFSUploadUtil {

    static {
        try {
            // 初始化FastDFS配置
            ClientGlobal.init(Config.getString("fdfs_conf_path"));
        } catch (Exception e) {
            throw new RuntimeException("初始化FastDFS客户端失败", e);
        }
    }

    /**
     * 上传字节数组到FastDFS
     *
     * 此方法接收一个字节数组和一个图片类型，处理其内容，并附带元数据（如作者信息），
     * 然后通过FastDFS的TrackerServer定位StorageServer，实现文件的上传。图片类型用于记录或影响文件存储或处理方式。
     * 成功后返回文件在FastDFS存储系统的路径，失败则抛出异常。
     *
     * @param fileBytes 字节数组，待上传文件的内容
     * @param imageType 字符串类型，表示图片类型，可用于分类或处理逻辑
     * @return 字符串类型，表示文件在FastDFS中的存储路径
     * @throws IOException       文件处理过程中发生的I/O异常
     * @throws MyException      FastDFS操作相关的异常
     */
    public static String uploadFile(byte[] fileBytes, String imageType) throws IOException, MyException {
        // 准备文件元数据，包括作者名和图片类型
        NameValuePair[] metaList = new NameValuePair[]{
                new NameValuePair("author", "username"), // 注意这里的"username"应根据实际情况动态获取
                new NameValuePair("image_type", imageType)
        };

        // 初始化TrackerClient并获取TrackerServer实例
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();

        // 创建StorageClient实例，storageServer设为null以自动发现
        StorageServer storageServer = null;
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);

        // 执行文件上传，直接使用字节数组，同时传递文件类型和元数据
        // 注意：此处假设文件名由系统生成或从其他元数据推断，故省略filename参数
        String[] uploadResults = storageClient.upload_file(null, fileBytes, "image/" + imageType, metaList);

        // 检查并返回上传结果路径，或在失败时抛出异常
        if (uploadResults != null && uploadResults.length == 2) {
            return uploadResults[0] + "/" + uploadResults[1];
        } else {
            throw new IOException("文件上传失败");
        }
    }
}